package org.gongliang.jsmile.gen.gentable;

import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.ResultSet;
import java.util.List;

import org.gongliang.jsmile.gen.db.DBUtils;
import org.gongliang.jsmile.gen.db.StrUtil;

import com.google.common.collect.Lists;

public class GenTables {

	private String[] removedTableNamePrefixes = null;
	private String[] tableNames = null;
	private Connection conn = null;
	private String basePackname = null;
	private String mybatisPath = null;

	public GenTables(String basePackname) {
		this.conn = DBUtils.getConnection();
		this.basePackname = basePackname;
	}

	public static GenTables me(String baseEntityPackname) {
		return new GenTables(baseEntityPackname);
	}

	/**
	 * 自动生成代码，返回Table实体
	 */
	public List<Table> getTables() {
		List<Table> tables = Lists.newArrayList();
		try {
			DatabaseMetaData dbmd = conn.getMetaData();
			if (tableNames != null && tableNames.length > 0) {
				for (int i = 0; i < tableNames.length; i++) {
					String primarykey = null;
					Table table = new Table();
					table.setTableName(tableNames[i]);
					table.setEntityPackageName(basePackname);
					table.setMybatisPath(mybatisPath);
					table.setClassName(getRealTableName(tableNames[i]));
					List<Column> columnsList = Lists.newArrayList();
					ResultSet rs = dbmd.getColumns(null, null, tableNames[i], "%");
					ResultSet primaryKeys = dbmd.getPrimaryKeys(conn.getCatalog(), null, tableNames[i]);
					while (primaryKeys.next()) {
						primarykey = primaryKeys.getString("COLUMN_NAME");
					}
					table.setPrimarykey(primarykey);
					while (rs.next()) {
						String columnName = rs.getString("COLUMN_NAME");
						Column column = new Column();
						column.setColumnName(columnName);
						column.setColumnDesc(rs.getString("REMARKS"));
						column.setColumnType(sqlType2JavaType(rs.getString("COLUMN_NAME"), rs.getString("TYPE_NAME")));
						if (null!=primarykey&&primarykey.equals(column.getColumnName())) {
							column.setIsPrimaryKey("true");
						}
						columnsList.add(column);
					}
					table.setColumns(columnsList);
					tables.add(table);
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			DBUtils.close(conn);
		}
		return tables;
	}



	/**
	 * 获取实体名称
	 */
	public String getRealTableName(String tablename) {
		String str = tablename;
		if (removedTableNamePrefixes != null && removedTableNamePrefixes.length > 0) {
			for (String s : removedTableNamePrefixes) {
				if(tablename.contains(s)) {
					str = str.substring(s.length(), str.length());
					break;
				}
			}
		}
		str = StrUtil.underlineToCamelhump(str);
		str = StrUtil.firstCharToUpperCase(str);
		return str;
	}

	/**
	 * 功能：获得列的数据类型
	 * 
	 * @param sqlType
	 * @return
	 */
	private String sqlType2JavaType(String columnName, String sqlType) {
		if (sqlType.equalsIgnoreCase("bit")) {
			return "Boolean";
		} else if (sqlType.equalsIgnoreCase("tinyint")) {
			return "Boolean";
		} else if (sqlType.equalsIgnoreCase("smallint")) {
			return "Integer";
		} else if (sqlType.equalsIgnoreCase("int")) {
			return "Integer";
		} else if (sqlType.equalsIgnoreCase("bigint")) {
			return "Integer";
		} else if (sqlType.equalsIgnoreCase("float")) {
			return "Float";
		}else if (sqlType.equalsIgnoreCase("double")) {
			return "java.math.BigDecimal";
		} else if (sqlType.equalsIgnoreCase("decimal") || sqlType.equalsIgnoreCase("numeric") || sqlType.equalsIgnoreCase("real")
				|| sqlType.equalsIgnoreCase("money") || sqlType.equalsIgnoreCase("smallmoney")) {
			return "java.math.BigDecimal";
		} else if (sqlType.equalsIgnoreCase("varchar") || sqlType.equalsIgnoreCase("char") || sqlType.equalsIgnoreCase("nvarchar")
				|| sqlType.equalsIgnoreCase("nchar") || sqlType.equalsIgnoreCase("text")) {
			return "String";
		} else if (sqlType.equalsIgnoreCase("datetime") || sqlType.equalsIgnoreCase("timestamp")) {
			return "java.util.Date";
		} else if (sqlType.equalsIgnoreCase("image")) {
			return "java.sql.Blod";
		} else if (sqlType.equalsIgnoreCase("boolean")) {
			return "Boolean";
		}

		return null;
	}

	public void setTableNames(String... tableNames) {
		this.tableNames = tableNames;
	}

	public void setRemovedTableNamePrefixes(String... removedTableNamePrefixes) {
		this.removedTableNamePrefixes = removedTableNamePrefixes;
	}

	public String getBasePackname() {
		return basePackname;
	}

	public void setBasePackname(String basePackname) {
		if (mybatisPath == null) {
			throw new RuntimeException("实体类包名不能为空!");
		}
		this.basePackname = basePackname;
	}

	public void setMybatisPath(String mybatisPath) {
		if (mybatisPath == null) {
			throw new RuntimeException("mybatis路径不能为空!");
		}
		this.mybatisPath = mybatisPath;
	}
}
